package com.swak.vertx.config;

import java.io.File;
import java.util.Set;

import com.swak.App;
import com.swak.Constants;
import com.swak.Env;
import com.swak.utils.Sets;
import com.swak.vertx.access.Access;
import com.swak.vertx.protocol.http.error.Error400;
import com.swak.vertx.security.SecurityHandler;
import com.swak.vertx.transport.VertxProxy;

import io.vertx.core.Vertx;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.ext.web.handler.CorsHandler;

/**
 * 路由配置项目
 *
 * @author: lifeng
 * @date: 2020/3/29 19:08
 */
public interface RouterConfig extends AbstractConfig {

	/**
	 * 对 router 进行配置
	 *
	 * @param vertx  代理vertx
	 * @param router router
	 */
	void apply(Vertx vertx, Router router);

	/**
	 * 开发环境的配置: 注意新版的的chrome 浏览器不支持IP模式的跨域调用，在开发模式下可以做一个Nginx 的反向代理
	 * 
	 * @param security
	 * @param properties
	 * @return
	 */
	public static RouterConfig defConfig(App app, VertxProxy proxy, SecurityHandler security) {
		return (vertx, router) -> {

			VertxConfig config = proxy.config();

			/*
			 *  跨域的配置，如果发布环境，默许在 Nginx 中配置
			 */
			if (app.getEvn() != Env.prod) {
				Set<String> headers = Sets.newHashSet();
				headers.add(Constants.Cors_Ajax_Header);
				headers.add(Constants.Cors_Content_Type_Header);
				headers.add(Constants.Platform_NAME);
				headers.add(Constants.App_NAME);
				headers.add(Constants.Open_NAME);
				headers.add(Constants.Client_NAME);
				headers.add(config.getTokenName());
				router.route()
						.handler(CorsHandler.create().addRelativeOrigin(Constants.Cors_Allowed_Origin_For_Dev)
								.allowCredentials(true).allowedHeaders(headers)
								.maxAgeSeconds(Constants.Cors_Max_Age_Seconds_For_Dev));
			}

			/*
			 * 创建上传的目录
			 */
			File uploadDirectory = App.file(config.getUploadDirectory(), true);

			/*
			 * 标准的 Http Body 解析
			 */
			router.route()
					.handler(BodyHandler.create(uploadDirectory.getAbsolutePath()).setBodyLimit(config.getBodyLimit())
							.setDeleteUploadedFilesOnEnd(config.isDeleteUploadedFilesOnEnd()));

			/*
			 * 访问记录
			 */
			router.route().handler(Access.access());

			/*
			 *  Api安全
			 */
			if (security != null) {
				router.route().handler(security.routingHandler());
			}

			/*
			 * 400 处理
			 */
			router.errorHandler(400, new Error400());
		};
	}
}
